package com.smartwrite.controller;

import com.smartwrite.dto.TaskResultResponse;
import com.smartwrite.dto.TaskStatusResponse;
import com.smartwrite.service.TaskStorageService;
import com.smartwrite.entity.TaskInfo;
import com.smartwrite.enums.TaskStatus;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class TaskStatusController {
    
    private final TaskStorageService taskStorageService;
    
    @GetMapping("/status/{taskId}")
    public ResponseEntity<?> getTaskStatus(@PathVariable String taskId) {
        try {
            TaskInfo taskInfo = taskStorageService.getTask(taskId);
            
            if (taskInfo == null) {
                // Try to load from file system
                taskInfo = loadTaskFromFileSystem(taskId);
                if (taskInfo == null) {
                    return ResponseEntity.notFound().build();
                }
            }
            
            // Update status if done file exists
            updateTaskStatusFromDoneFile(taskInfo);
            
            // Calculate elapsed time
            double elapsedTime = (Instant.now().toEpochMilli() - taskInfo.getStartTime().toEpochMilli()) / 1000.0;
            
            TaskStatusResponse response = TaskStatusResponse.builder()
                    .taskId(taskId)
                    .status(taskInfo.getStatusCode())  // 使用getStatusCode()方法
                    .error(taskInfo.getError())
                    .elapsedTime(elapsedTime)
                    .model(taskInfo.getModel())
                    .searchEngine(taskInfo.getSearchEngine())
                    .build();
                    
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Error getting task status for {}: {}", taskId, e.getMessage());
            return ResponseEntity.internalServerError()
                    .body(Map.of("error", "Internal server error"));
        }
    }
    
    @GetMapping("/result/{taskId}")
    public ResponseEntity<?> getTaskResult(@PathVariable String taskId) {
        try {
            TaskInfo taskInfo = taskStorageService.getTask(taskId);
            
            if (taskInfo == null) {
                // Try to load from file system
                taskInfo = loadTaskFromFileSystem(taskId);
                if (taskInfo == null) {
                    return ResponseEntity.notFound().build();
                }
            }
            
            String result = taskInfo.getResult();
            
            // If result is not in memory, try to load from report.md file
            if (result == null || result.isEmpty()) {
                result = loadResultFromFile(taskId);
                if (result == null) {
                    return ResponseEntity.badRequest()
                            .body(Map.of("error", "Task result not available"));
                }
                // Update task info with loaded result
                taskInfo.setResult(result);
                taskStorageService.updateTask(taskInfo);
            }
            
            TaskResultResponse response = TaskResultResponse.builder()
                    .taskId(taskId)
                    .result(result)
                    .model(taskInfo.getModel())
                    .searchEngine(taskInfo.getSearchEngine())
                    .build();
                    
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Error getting task result for {}: {}", taskId, e.getMessage());
            return ResponseEntity.internalServerError()
                    .body(Map.of("error", "Internal server error"));
        }
    }
    
    private TaskInfo loadTaskFromFileSystem(String taskId) {
        try {
            Path taskDir = Paths.get(taskStorageService.getResultsDir(), taskId);
            if (!Files.exists(taskDir)) {
                return null;
            }
            
            Path resultFile = taskDir.resolve("result.jsonl");
            Path doneFile = taskDir.resolve("done.txt");
            
            if (!Files.exists(resultFile)) {
                return null;
            }
            
            // Get creation time
            Instant creationTime = Files.getLastModifiedTime(taskDir).toInstant();
            
            TaskInfo taskInfo = new TaskInfo();
            taskInfo.setTaskId(taskId);
            taskInfo.setStatus(Files.exists(doneFile) ? "completed" : "running");
            taskInfo.setStartTime(creationTime);
            
            // Try to load result from result.jsonl
            try {
                String resultContent = Files.readString(resultFile);
                // Parse JSON and extract result field
                // This is a simplified version - you might want to use Jackson for proper JSON parsing
                taskInfo.setResult(resultContent);
            } catch (Exception e) {
                log.error("Error loading result file for {}: {}", taskId, e.getMessage());
                taskInfo.setError("Failed to load output file: " + e.getMessage());
            }
            
            // Store in memory for future access
            taskStorageService.createTask(taskInfo);
            
            return taskInfo;
            
        } catch (IOException e) {
            log.error("Error loading task from file system: {}", e.getMessage());
            return null;
        }
    }
    
    private void updateTaskStatusFromDoneFile(TaskInfo taskInfo) {
        if (taskInfo.getStatus() == TaskStatus.RUNNING) {
            Path doneFile = Paths.get(taskStorageService.getResultsDir(), 
                    taskInfo.getTaskId(), "done.txt");
            if (Files.exists(doneFile)) {
                taskInfo.setStatus(TaskStatus.COMPLETED);
                taskStorageService.updateTask(taskInfo);
            }
        }
    }
    
    private String loadResultFromFile(String taskId) {
        try {
            Path reportFile = Paths.get(taskStorageService.getResultsDir(), 
                    "records", taskId, "report.md");
            if (Files.exists(reportFile)) {
                return Files.readString(reportFile);
            }
        } catch (IOException e) {
            log.error("Error loading result from file for {}: {}", taskId, e.getMessage());
        }
        return null;
    }
}